package com.cs410.collabwriting.main;

import java.util.ArrayList;

import com.cs410.collabwriting.tools.DatabaseManager;
import com.cs410.collabwriting.tools.queryTools.DatabaseTable;
import com.cs410.collabwriting.tools.queryTools.QueryBuilder;
import com.cs410.collabwriting.tools.queryTools.QueryCondition;
import com.cs410.collabwriting.tools.queryTools.QueryType;
import com.cs410.collabwriting.tools.queryTools.tables.TAG_TABLE;

public class TagManager implements Manager {
	
	private static TagManager s_tagManager = null;

	private TagManager() {
		
	}
	
	public boolean addTag( int storyID, String userID, String tag ) {
		int addedTag = DatabaseManager.executeUpdate(
				new QueryBuilder(QueryType.INSERT)
				.addColumns(TAG_TABLE.STORYID, TAG_TABLE.USERID, TAG_TABLE.TAG)
				.addTables(DatabaseTable.TAG_TABLE)
				.addValues( String.valueOf(storyID), QueryBuilder.toSQLChar(userID) ,  QueryBuilder.toSQLChar(tag) )
				.value() );
		return addedTag > 0 ? true : false;
	}

	//Returns how many users had tagged this story with this particular tag
	public int getStoryTagCount( int storyID, String tag ) {
		int count = 0;
		String countInString = DatabaseManager.executeExactQuery(
				new QueryBuilder(QueryType.SELECTION)
				.addColumns("COUNT(*)")
				.addTables(DatabaseTable.TAG_TABLE)
				.addConditions(QueryCondition.AND, TAG_TABLE.STORYID, QueryCondition.EQ, storyID )
				.addConditions(QueryCondition.AND, TAG_TABLE.TAG, QueryCondition.EQ, QueryBuilder.toSQLChar(tag))				
				.value() );
		count = countInString == null ? 0 : Integer.parseInt(countInString);
		return count;
	
	}
	
	public ArrayList<String> getUserTags ( String userID, int storyID ) {
		ArrayList<String[]> tagResults = DatabaseManager.executeQueryWithColumnNames(
				new QueryBuilder(QueryType.SELECTION)
				.addColumns( TAG_TABLE.TAG )
				.addTables(DatabaseTable.TAG_TABLE)
				.addConditions(QueryCondition.AND, TAG_TABLE.STORYID, QueryCondition.EQ, storyID )
				.addConditions(QueryCondition.AND, TAG_TABLE.USERID, QueryCondition.EQ, QueryBuilder.toSQLChar(userID))				
				.value() );
		ArrayList<String> allTags = DatabaseManager.getValuesInColumn(tagResults, TAG_TABLE.TAG);
		return allTags;
	}
	
	public static TagManager getInstance() {
		if( s_tagManager == null ) {
			s_tagManager = new TagManager();
		}
		return s_tagManager;
	}



	@Override
	public ArrayList<DatabaseObjects> getAll() {

		return null;
	}
	
	@Override
	public void update() {
		;// does not need to do anything on update
	}

    public boolean updateTags(int storyID, String userID, String[] tags) {
        boolean updated = false;
        
        if (tags.length > 0) {
            ArrayList<String> list = getUserTags(userID, storyID);
            
            String sql = "INSERT INTO " + DatabaseTable.TAG_TABLE + "(" + 
                    TAG_TABLE.STORYID + "," + TAG_TABLE.TAG + "," + TAG_TABLE.USERID + ") VALUES ";      
            boolean update = false;
            
            for (String tag: tags) {
                if (!list.contains(tag)) {
                	sql = sql.concat( (update ? "," : "").concat(" (" + storyID + ",'" + tag + "','" + userID + "')"));                    
                    update = true;
                }
            }
            
            if (update) {
                updated = (DatabaseManager.executeUpdate(sql) > 0); 
            }
        }
        
        QueryBuilder qb = new QueryBuilder( QueryType.DELETE )
            .addTables( DatabaseTable.TAG_TABLE )
            .addConditions( QueryCondition.AND, TAG_TABLE.STORYID, QueryCondition.EQ, storyID)
            .addConditions( QueryCondition.AND, TAG_TABLE.USERID, QueryCondition.EQ, userID);
        
        for (String tag : tags) {
            qb.addConditions( QueryCondition.AND, TAG_TABLE.TAG, QueryCondition.NEQ, tag);
        }
        
        DatabaseManager.executeUpdate(qb); 
        
        return updated;
    }

}
